import { invoke } from '@tauri-apps/api/core';
import { DeleteCondition, DeleteOptions, QueryCondition, QueryExtention, QueryOptions, ComparsionOperator, UpdateCondition, UpdateOptions } from '../types';
import optionsWrap from '@/components/datasets/create/website/base/options-wrap';
import { DataSource } from '@/services/data-source';

export const dsFindOneById = async (ds: number | DataSource, classIdentifier: string, id: string): Promise<any> => {
    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }
    let res = await invoke('plugin:mg-platform|ds_find_one_by_id', {
        dsId,
        datasource: datasource, classIdentifier: classIdentifier, id: id
    });
    console.log(res);
    return res;
}

export const dsFindOne = async (ds: number | DataSource, classIdentifier: string, conditions: QueryCondition, extentions?: any, options?: any): Promise<any> => {

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res = await invoke('plugin:mg-platform|ds_find_one', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        conditions: conditions,
        extentions: extentions,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsFind = async (ds: number | DataSource, classIdentifier: string, conditions: QueryCondition, extentions?: QueryExtention, options?: any)
    : Promise<{ total: number, data: Array<any> }> => {
    console.log(classIdentifier, conditions, extentions, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res: any = await invoke('plugin:mg-platform|ds_find', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        conditions: conditions,
        extentions: extentions,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsBatchFind = async (ds: number | DataSource, items: Array<any[]>, options?: any)
    : Promise<{ total: number, data: Array<any> }> => {
    console.log(items, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res: any = await invoke('plugin:mg-platform|ds_batch_query', {
        dsId,
        datasource: datasource,
        items: items,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsInsert = async (ds: number | DataSource, classIdentifier: string, values: { [key: string]: any }, options?: any)
    : Promise<any> => {
    console.log(classIdentifier, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res = await invoke('plugin:mg-platform|ds_insert', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        values: values,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsBatchInsert = async (ds: number | DataSource, items: Array<any[]>, options?: any)
    : Promise<any> => {
    console.log(items, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res = await invoke('plugin:mg-platform|ds_batch_insert', {
        dsId,
        datasource: datasource,
        items: items,
        options: options,
    });
    console.log(res);
    return res;
}


export const dsDelete = async (ds: number | DataSource, classIdentifier: string, conditions: DeleteCondition, options?: DeleteOptions)
    : Promise<any> => {
    console.log(classIdentifier, conditions, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res = await invoke('plugin:mg-platform|ds_delete', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        conditions: conditions,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsBatchDelete = async (ds: number | DataSource, items: Array<any[]>, options?: DeleteOptions)
    : Promise<Array<any>> => {
    console.log(items, options);

    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }

    let res: any = await invoke('plugin:mg-platform|ds_batch_delete', {
        dsId,
        datasource: datasource,
        items: items,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsDeleteById = async (ds: number | DataSource, classIdentifier: string, id: number)
    : Promise<any> => {
    console.log(classIdentifier, id);

    let res = await dsDelete(ds, classIdentifier, {
        attributes: [
            {
                name: 'id',
                operator: ComparsionOperator.Equal,
                value: id + ''
            }
        ]
    });
    return res;
}

export const dsUpdate = async (ds: number | DataSource, classIdentifier: string, conditions: UpdateCondition, values: { [key: string]: any }, options?: UpdateOptions)
    : Promise<any> => {
    console.log(classIdentifier, conditions, values, options);
    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }
    let res = await invoke('plugin:mg-platform|ds_update', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        conditions: conditions,
        values: values,
        options: options,
    });
    console.log(res);
    return res;
}


export const dsBatchUpdate = async (ds: number, items: Array<any[]>, options?: UpdateOptions)
    : Promise<any> => {
    console.log(items, options);
    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }
    let res = await invoke('plugin:mg-platform|ds_batch_update', {
        dsId,
        datasource: datasource,
        items: items,
        options: options,
    });
    console.log(res);
    return res;
}

export const dsUpdateByKeys = async (ds: number | DataSource, classIdentifier: string, keys: string[], values: { [key: string]: any }, options?: UpdateOptions)
    : Promise<any> => {
    console.log(classIdentifier, keys, values, options);
    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }
    let res = await invoke('plugin:mg-platform|ds_update_by_keys', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        keys: keys,
        values: values,
        options: options,
    });
    console.log(res);
    return res;
}


export const dsUpdateById = async (ds: number | DataSource, classIdentifier: string, id: number | string, values: { [key: string]: any }, options?: UpdateOptions)
    : Promise<any> => {
    console.log(classIdentifier, id, values, options);
    let dsId = 0;
    let datasource: DataSource | null = null;

    if (typeof ds === 'object') {
        datasource = ds;
    } else {
        dsId = ds as number;
    }
    let res = await invoke('plugin:mg-platform|ds_update', {
        dsId,
        datasource: datasource,
        classIdentifier: classIdentifier,
        conditions: {
            attributes: [
                {
                    name: 'id',
                    operator: ComparsionOperator.Equal,
                    value: id + ''
                }
            ]
        },
        values: values,
        options: options,
    });
    console.log(res);
    return res;
}



export const mergeQueryCondition = (conditoins: QueryCondition[]): QueryCondition => {
    let temp = {};
    for (let i = 0; i < conditoins.length; i++) {
        temp = Object.assign(temp, conditoins[i]);
    }
    return temp
}

export const mergeQueryExtention = (conditoins: QueryExtention[]): QueryExtention => {
    let temp = {};
    for (let i = 0; i < conditoins.length; i++) {
        temp = Object.assign(temp, conditoins[i]);
    }
    return temp;
}

export const mergeQueryOptions = (conditoins: QueryOptions[]): QueryOptions => {
    let temp = {};
    for (let i = 0; i < conditoins.length; i++) {
        temp = Object.assign(temp, conditoins[i]);
    }
    return temp
}